package com.yfbao.horizon.schedule.tk.meter;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;


/**
 * Spring AOP 的代理机制默认基于 Java 动态代理 或 CGLIB。
 * Spring AOP 只能对 Spring 管理的 Bean 生效，并且默认情况下，
 * 只能拦截 Spring 管理的对象的方法调用。
 * 而 ReentrantLock 是 JDK 类，不是 Spring 管理的 Bean，因此 Spring AOP 无法直接对其进行代理。
 * 此AOP方案无效
 */

@Order(-1000000)
@Slf4j
@Aspect
@Component
public class LockMonitorAspect {


    @Before("execution(* java.util.concurrent.locks.ReentrantLock.tryLock())")
    public void beforeLock() {
        System.out.println("Attempting to acquire lock...");
    }

    @After("execution(* java.util.concurrent.locks.ReentrantLock.unlock())")
    public void afterUnlock() {
        System.out.println("Lock released.");
    }

    @Around("execution(* java.util.concurrent.locks.ReentrantLock.tryLock(..)) || execution(* java.util.concurrent.locks.ReentrantLock.lock(..))" +
            " || execution(* java.util.concurrent.locks.ReentrantLock.unlock(..))")
    public Object monitorReentrantLock(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long endTime = System.currentTimeMillis();
            if ("lock".equals(joinPoint.getSignature().getName())) {
                log.info("ReentrantLock acquired in {} milliseconds", endTime - startTime);
            } else {
                log.info("ReentrantLock released in {} milliseconds", endTime - startTime);
            }
        }
    }

//    @Around("execution(* *(..)) && synchronized(this)")
//    public Object monitorSynchronizedLock(ProceedingJoinPoint joinPoint) throws Throwable {
//        long startTime = System.currentTimeMillis();
//        log.info("Thread {} is about to enter synchronized block of method {}", Thread.currentThread().getName(), joinPoint.getSignature());
//        try {
//            return joinPoint.proceed();
//        } finally {
//            long endTime = System.currentTimeMillis();
//            log.info("Thread {} exited synchronized block of method {} in {} milliseconds", Thread.currentThread().getName(), joinPoint.getSignature(), endTime - startTime);
//        }
//    }
}
